#include "stm32f0xx_usart.h"
#include "CRC16.h"

#include "IR_Control.h"
#include "parameter.h"

#include "stdio.h"
#include "string.h"

#define HEADER_L 0xA5
#define HEADER_H 0x55

#define REPLAY_MAX 3

//volatile
//volatile unsigned char uc_SendBuf[10];
static unsigned char uc_SendBuf[10];


Str_IR_Para str_LocalIR_Para;
unsigned char Uart_IR_Recv_Buf[IR_RECV_BUF_LENGTH];
unsigned char uc_IR_Rx_Finish = 0;
unsigned char uc_LearnChannel = 1;
unsigned char uc_IRLearnFlag = 0;
static unsigned char uc_ReplayCount = 0;

static void GetAirState(unsigned char state);
static void UseRegOpenAirCondit(void);
void UseRegCloseAirCondit(void);

static void IR_SendData(unsigned int length)
{
    unsigned int i;
    for(i = 0; i < length; i++)
    {
    	USART_SendData(USART1,uc_SendBuf[i]);
    	while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
//    	printf("%x ",uc_SendBuf[i]);
    }
}


const unsigned char IR_CMD[][6] =
{
	{0xA5, 0x03, 0x00, 0x20, 0x00, 0x01},	//获取空调代码号
	{0xA5, 0x03, 0x00, 0x25, 0x00, 0x01},	//空调电源状态
	{0xA5, 0x03, 0x00, 0x26, 0x00, 0x01},	//空调温度状态
	{0xA5, 0x03, 0x00, 0x27, 0x00, 0x01},	//空调模式状态
	{0xA5, 0x03, 0x00, 0x28, 0x00, 0x01},	//空调风速状态
	{0xA5, 0x03, 0x00, 0x29, 0x00, 0x01},	//空调灯光状态

	//	测试红外学习 0018H
//	0xA5, 0x06, 0x00, 0x20, 0x00, 0x01,	//空调匹配,空调码库代号
	{0xA5, 0x06, 0x00, 0x10, 0x00, 0x01},	//空调自动匹配
	{0xA5, 0x06, 0x00, 0x16, 0x00, 0x3F},	//启动红外学习 通道值：0000H-003FH
	{0xA5, 0x06, 0x00, 0x17, 0x00, 0x3F}	,  //停止红外学习
	{0xA5, 0x06, 0x00, 0x18, 0x00, 0x3F} //测试红外学习

	//红外学习：通道1：open 通道2：close
//	3：温度+  4：温度-
	//5：6：模式

};

void GetCurrentAirCode(void)
{
	GetAirFormat();
	HAL_Delay(15);
	ReadIRFormat();
}

void GetAirFormat(void)
{
	unsigned short ui_CRC;
	int i;
	for(i=0;i<6;i++)
	{
		uc_SendBuf[i] = IR_CMD[0][i];
	}

	 ui_CRC = CRC16(uc_SendBuf,6);

	 uc_SendBuf[6]  = ui_CRC & 0x00ff;
	 uc_SendBuf[7]  = ui_CRC >> 8;

	 IR_SendData(8);
}



void SetAirFormat(unsigned short format)
{
		unsigned short ui_CRC;
		int i;
		for(i=0;i<6;i++)
		{
			uc_SendBuf[i] = IR_CMD[0][i];
		}

		uc_SendBuf[1] = 0x06;

		uc_SendBuf[4] = format>>8;
		uc_SendBuf[5] = format&0xff;

		 ui_CRC = CRC16(uc_SendBuf,6);

		 uc_SendBuf[6]  = ui_CRC & 0x00ff;
		 uc_SendBuf[7]  = ui_CRC >> 8;

		 IR_SendData(8);

}


void GetAirPowerState(void)
{
	GetAirState(1);
}

void GetAirTempState(void)
{
	GetAirState(2);
}

void GetAirModeState(void)
{
	GetAirState(3);
}

void GetAirFanState(void)
{
	GetAirState(4);
}


void GetAirLightState(void)
{
	GetAirState(5);
}

void SetAirTemperatureUp(void)
{
//	if(str_Device_Param.str_DeviceParam.IRUseDefCodeFlag)
	{
		ContrlUseLearnChannel(3);
	}
}

/*参数：Temperature 取值 16~30*/
void SetAirTemperature(unsigned char Temperature)
{
	unsigned short ui_CRC;
		int i;
		for(i=0;i<6;i++)
		{
			uc_SendBuf[i] = IR_CMD[2][i];
		}
		uc_SendBuf[1] = 0x06;

		uc_SendBuf[5] = Temperature - 16; //0-e 对应16-30度

		 ui_CRC = CRC16(uc_SendBuf,6);

		 uc_SendBuf[6]  = ui_CRC & 0x00ff;
		 uc_SendBuf[7]  = ui_CRC >> 8;

		 IR_SendData(8);
}

void AutoSetAirFormat(void)
{
	unsigned short ui_CRC;
	int i;
	for(i=0;i<6;i++)
	{
		uc_SendBuf[i] = IR_CMD[6][i];
	}

	 ui_CRC = CRC16(uc_SendBuf,6);

	 uc_SendBuf[6]  = ui_CRC & 0x00ff;
	 uc_SendBuf[7]  = ui_CRC >> 8;

	 IR_SendData(8);

}


void ContrlUseLearnChannel(unsigned char CtrlChannel)
{
	unsigned short ui_CRC;
	int i;
	for(i=0;i<6;i++)
	{
		uc_SendBuf[i] = IR_CMD[9][i];
	}

	uc_SendBuf[5] = CtrlChannel;

	 ui_CRC = CRC16(uc_SendBuf,6);

	 uc_SendBuf[6]  = ui_CRC & 0x00ff;
	 uc_SendBuf[7]  = ui_CRC >> 8;

	 IR_SendData(8);
}

void StartIRLearn(unsigned char LearnChannel)
{
	unsigned short ui_CRC;
	int i;
	for(i=0;i<6;i++)
	{
		uc_SendBuf[i] = IR_CMD[7][i];
	}

	uc_SendBuf[5] = LearnChannel;

	 ui_CRC = CRC16(uc_SendBuf,6);

	 uc_SendBuf[6]  = ui_CRC & 0x00ff;
	 uc_SendBuf[7]  = ui_CRC >> 8;

	 IR_SendData(8);
}


void StopIRLearn(unsigned char LearnChannel)
{
	unsigned short ui_CRC;
	int i;
	for(i=0;i<6;i++)
	{
		uc_SendBuf[i] = IR_CMD[8][i];
	}

	uc_SendBuf[5] = LearnChannel;

	ui_CRC = CRC16(uc_SendBuf,6);

	 uc_SendBuf[6]  = ui_CRC & 0x00ff;
	 uc_SendBuf[7]  = ui_CRC >> 8;

	 IR_SendData(8);

}

static void GetAirState(unsigned char state)
{
	unsigned short ui_CRC;
	int i;
	for(i=0;i<6;i++)
	{
		uc_SendBuf[i] = IR_CMD[state][i];
	}

	 ui_CRC = CRC16(uc_SendBuf,6);

	 uc_SendBuf[6]  = ui_CRC & 0x00ff;
	 uc_SendBuf[7]  = ui_CRC >> 8;

	 IR_SendData(8);
}

//str_Device_Param.str_DeviceParam.IRUseDefCodeFlag

void openAirCondit(void)
{
	if(str_Device_Param.str_DeviceParam.IRUseDefCodeFlag)
	{
		ContrlUseLearnChannel(1);
	}
	else
	{
		UseRegOpenAirCondit();
	}

}

static void UseRegOpenAirCondit(void)
{
	unsigned short ui_CRC;
	int i;
	for(i=0;i<6;i++)
	{
		uc_SendBuf[i] = IR_CMD[1][i];
	}

	uc_SendBuf[1] = 0x06;

	 ui_CRC = CRC16(uc_SendBuf,6);

	 uc_SendBuf[6]  = ui_CRC & 0x00ff;
	 uc_SendBuf[7]  = ui_CRC >> 8;

	 IR_SendData(8);
}

void CloseAirCondit(void)
{
	if(str_Device_Param.str_DeviceParam.IRUseDefCodeFlag)
		{
			ContrlUseLearnChannel(1);
		}
		else
		{
			UseRegCloseAirCondit();
		}
}

void UseRegCloseAirCondit(void)
{
	unsigned short ui_CRC;
	int i;
	for(i=0;i<6;i++)
	{
		uc_SendBuf[i] = IR_CMD[1][i];
	}

	uc_SendBuf[1] = 0x06;

	uc_SendBuf[5] = 0x00;

	 ui_CRC = CRC16(uc_SendBuf,6);

	 uc_SendBuf[6]  = ui_CRC & 0x00ff;
	 uc_SendBuf[7]  = ui_CRC >> 8;

	 IR_SendData(8);
}


void ReadIRFormat(void)
{
    int i;
    unsigned short ui_res;
    unsigned char CRC16_L,CRC16_H;
    printf("RecvIRFormat\r\n");

//    while(uc_IR_Rx_Finish == 0);

        for(i = 0; i < IR_RX_LENGTH;i++)
            printf("%x ",Uart_IR_Recv_Buf[i]);

        if((Uart_IR_Recv_Buf[0] == HEADER_L) && (Uart_IR_Recv_Buf[1] == 0x03))
        {

            ui_res = CRC16(Uart_IR_Recv_Buf,IR_RX_LENGTH - 2);

            CRC16_L = ui_res&0xff;
            CRC16_H = (ui_res&0xff00) >> 8;

            printf("CRC16_L = %x CRC16_H = %x\r\n",CRC16_L,CRC16_H);
           if((CRC16_L == Uart_IR_Recv_Buf[IR_RX_LENGTH - 2]) && (CRC16_H == Uart_IR_Recv_Buf[IR_RX_LENGTH - 1]))
            {
//                CMD
                //Format
                str_LocalIR_Para.fromat = (Uart_IR_Recv_Buf[3] << 8) + Uart_IR_Recv_Buf[4];
                str_LocalIR_Para.GetAirParaCount = 1;
            }

        }

}


void ReadAirStatus(void)
{
    int i;
    unsigned short ui_res;
    unsigned char CRC16_L,CRC16_H;
    printf("ReadAirStatus\r\n");

//    while(uc_IR_Rx_Finish == 0);

        for(i = 0; i < IR_RX_LENGTH;i++)
            printf("%x ",Uart_IR_Recv_Buf[i]);

        if((Uart_IR_Recv_Buf[0] == HEADER_L)&&((Uart_IR_Recv_Buf[1] == 0x03) ||(Uart_IR_Recv_Buf[1] == 0x06)))
        {

            ui_res = CRC16(Uart_IR_Recv_Buf,IR_RX_LENGTH - 2);

            CRC16_L = ui_res&0xff;
            CRC16_H = (ui_res&0xff00) >> 8;

            printf("CRC16_L = %x CRC16_H = %x\r\n",CRC16_L,CRC16_H);
           if((CRC16_L == Uart_IR_Recv_Buf[IR_RX_LENGTH - 2]) && (CRC16_H == Uart_IR_Recv_Buf[IR_RX_LENGTH - 1]))
            {
//                CMD
                //Format
                str_LocalIR_Para.AirState = Uart_IR_Recv_Buf[4];
                str_LocalIR_Para.GetAirParaCount = 2;
            }

        }

}

unsigned char ReadIRLearnStatus(void)
{
	int i;
	    unsigned short ui_res;
	    unsigned char CRC16_L,CRC16_H;

		for(i = 0; i < IR_RX_LENGTH;i++)
			printf("%x ",Uart_IR_Recv_Buf[i]);

	        if((Uart_IR_Recv_Buf[0] == HEADER_L) && (Uart_IR_Recv_Buf[1] == 0x03))
	        {

	            ui_res = CRC16(Uart_IR_Recv_Buf,IR_RX_LENGTH - 2);

	            CRC16_L = ui_res&0xff;
	            CRC16_H = (ui_res&0xff00) >> 8;

	            if((CRC16_L == Uart_IR_Recv_Buf[IR_RX_LENGTH - 2]) && (CRC16_H == Uart_IR_Recv_Buf[IR_RX_LENGTH - 1]))
	            {
	//                CMD
	            		if(Uart_IR_Recv_Buf[4]==0x80)
	            		{
	            			if(Uart_IR_Recv_Buf[5]==0x02)
	            			{
	            				printf("Learn Finish\r\n");
	            				uc_IRLearnFlag = 0;
	            				StopIRLearn(uc_LearnChannel);
	            				return 0x51;
	            			}
	            			else
	            			{
	            				printf("Learn Fail\r\n");
	            				return 0x52;
	            			}

	            		}
	            	}

	        }
	  return 0x52;
}

void ReadTRTest(void)
{
	int i;
	    unsigned short ui_res;
	    unsigned char CRC16_L,CRC16_H;
//	    printf("ReadTRTest\r\n");

	//    while(uc_IR_Rx_Finish == 0);

	        for(i = 0; i < IR_RX_LENGTH;i++)
	            printf("%x ",Uart_IR_Recv_Buf[i]);

	        if((Uart_IR_Recv_Buf[0] == HEADER_L) && (Uart_IR_Recv_Buf[1] == 0x03))
	        {

	            ui_res = CRC16(Uart_IR_Recv_Buf,IR_RX_LENGTH - 2);

	            CRC16_L = ui_res&0xff;
	            CRC16_H = (ui_res&0xff00) >> 8;

	            if((CRC16_L == Uart_IR_Recv_Buf[IR_RX_LENGTH - 2]) && (CRC16_H == Uart_IR_Recv_Buf[IR_RX_LENGTH - 1]))
	            {
	//                CMD
//	                str_LocalIR_Para.AirTemp = Uart_IR_Recv_Buf[4];
	                printf("ReadTRTest:%d\r\n",Uart_IR_Recv_Buf[4]);
	            }

	        }

}

void ReadIRTemp(void)
{
    int i;
    unsigned short ui_res;
    unsigned char CRC16_L,CRC16_H;
    printf("ReadIRTemp\r\n");

//    while(uc_IR_Rx_Finish == 0);

        for(i = 0; i < IR_RX_LENGTH;i++)
            printf("%x ",Uart_IR_Recv_Buf[i]);

        if((Uart_IR_Recv_Buf[0] == HEADER_L) && (Uart_IR_Recv_Buf[1] == 0x03))
        {

            ui_res = CRC16(Uart_IR_Recv_Buf,IR_RX_LENGTH - 2);

            CRC16_L = ui_res&0xff;
            CRC16_H = (ui_res&0xff00) >> 8;

            printf("CRC16_L = %x CRC16_H = %x\r\n",CRC16_L,CRC16_H);
           if((CRC16_L == Uart_IR_Recv_Buf[IR_RX_LENGTH - 2]) && (CRC16_H == Uart_IR_Recv_Buf[IR_RX_LENGTH - 1]))
            {
//                CMD
                str_LocalIR_Para.AirTemp = Uart_IR_Recv_Buf[4];
                str_LocalIR_Para.GetAirParaCount = 3;
            }

        }

}


void ReadAirMode(void)
{
    int i;
    unsigned short ui_res;
    unsigned char CRC16_L,CRC16_H;
    printf("ReadAirMode\r\n");

//    while(uc_IR_Rx_Finish == 0);

        for(i = 0; i < IR_RX_LENGTH;i++)
            printf("%x ",Uart_IR_Recv_Buf[i]);

        if((Uart_IR_Recv_Buf[0] == HEADER_L) && (Uart_IR_Recv_Buf[1] == 0x03))
        {

            ui_res = CRC16(Uart_IR_Recv_Buf,IR_RX_LENGTH - 2);

            CRC16_L = ui_res&0xff;
            CRC16_H = (ui_res&0xff00) >> 8;

            printf("CRC16_L = %x CRC16_H = %x\r\n",CRC16_L,CRC16_H);
           if((CRC16_L == Uart_IR_Recv_Buf[IR_RX_LENGTH - 2]) && (CRC16_H == Uart_IR_Recv_Buf[IR_RX_LENGTH - 1]))
            {
                str_LocalIR_Para.AirModel = Uart_IR_Recv_Buf[4];
                str_LocalIR_Para.GetAirParaCount = 4;
            }

        }

}


void Get_Air_ConditonData(void)
{
	while(str_LocalIR_Para.GetAirParaCount < 6)
		{

			switch(str_LocalIR_Para.GetAirParaCount)
			{
			 case 0:
				GetAirFormat();
				printf("GetAirFormat %d\r\n",str_LocalIR_Para.GetAirParaCount);
				HAL_Delay(10);
				ReadIRFormat();
				uc_ReplayCount++;
				if(uc_ReplayCount > REPLAY_MAX)
				{
					uc_ReplayCount = 0;
					str_LocalIR_Para.GetAirParaCount++;
					str_LocalIR_Para.fromat = 0xffff;
				}

				if(str_LocalIR_Para.GetAirParaCount == 1)
								uc_ReplayCount = 0;

			 break;
			 case 1:
				 GetAirPowerState();
				 printf("GetPowerState %d\r\n",str_LocalIR_Para.GetAirParaCount);
				 HAL_Delay(10);
				 ReadAirStatus();
				 uc_ReplayCount++;
				 if(uc_ReplayCount > REPLAY_MAX)
					{
						uc_ReplayCount = 0;
						str_LocalIR_Para.GetAirParaCount++;
						str_LocalIR_Para.AirState = 0xff;
					}
				 if(str_LocalIR_Para.GetAirParaCount == 2)
				 							uc_ReplayCount = 0;
				 	 break;
			 case 2:
				 GetAirTempState();
				 printf("GetAirTempState %d\r\n",str_LocalIR_Para.GetAirParaCount);

				 HAL_Delay(10);
				 ReadIRTemp();
				 uc_ReplayCount++;
				 if(uc_ReplayCount > REPLAY_MAX)
					{
						uc_ReplayCount = 0;
						str_LocalIR_Para.GetAirParaCount++;
						str_LocalIR_Para.AirTemp = 0xff;
					}
				 if(str_LocalIR_Para.GetAirParaCount == 3)
				 							uc_ReplayCount = 0;
				 break;
			 case 3:
				 GetAirModeState();
				 HAL_Delay(10);
				 ReadAirMode();

				 uc_ReplayCount++;
				 if(uc_ReplayCount > REPLAY_MAX)
					{
						uc_ReplayCount = 0;
						str_LocalIR_Para.GetAirParaCount++;
						str_LocalIR_Para.AirModel = 0xff;
					}
				 if(str_LocalIR_Para.GetAirParaCount == 4)
				 							uc_ReplayCount = 0;
			 		  break;
			 case 4:
				 GetAirFanState();

				 uc_ReplayCount++;
				 //if(uc_ReplayCount > REPLAY_MAX)
					{
						uc_ReplayCount = 0;
						str_LocalIR_Para.GetAirParaCount++;
						str_LocalIR_Para.AirFan = 0xff;
					}
				 if(str_LocalIR_Para.GetAirParaCount == 5)
				 							uc_ReplayCount = 0;
			 		  break;
			 case 5:
				 GetAirLightState();

				 uc_ReplayCount++;
				 //if(uc_ReplayCount > REPLAY_MAX)
					{
						uc_ReplayCount = 0;
						str_LocalIR_Para.GetAirParaCount++;
						str_LocalIR_Para.AirLight = 0xff;
					}

				 if(str_LocalIR_Para.GetAirParaCount == 6)
				 							uc_ReplayCount = 0;
			 		  break;
			 case 6:
	//			 AutoSetAirFormat();

				 uc_ReplayCount++;
				 //if(uc_ReplayCount > 1)
					{
						uc_ReplayCount = 0;
						str_LocalIR_Para.GetAirParaCount++;
					}

				 if(str_LocalIR_Para.GetAirParaCount == 7)
							 		uc_ReplayCount = 0;
				 break;
			 default:
			     break;
			} 
			memset(Uart_IR_Recv_Buf,0,IR_RX_LENGTH);
		}
}

